package com.ruoyi.business.service.koc.impl;

import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.dto.admin.user.AdjustUserPointsDTO;
import com.ruoyi.business.domain.dto.admin.user.UserKocSetDTO;
import com.ruoyi.business.domain.dto.api.user.UpdateUserDTO;
import com.ruoyi.business.domain.koc.TbKocLevel;
import com.ruoyi.business.domain.koc.TbUser;
import com.ruoyi.business.domain.koc.TbUserKocPointsLog;
import com.ruoyi.business.domain.koc.TbUserThirdIdentity;
import com.ruoyi.business.domain.vo.business.TbUserDetailVO;
import com.ruoyi.business.domain.wecom.*;
import com.ruoyi.business.mapper.koc.TbKocLevelMapper;
import com.ruoyi.business.mapper.koc.TbUserKocPointsLogMapper;
import com.ruoyi.business.mapper.koc.TbUserMapper;
import com.ruoyi.business.service.koc.ITbUserService;
import com.ruoyi.business.service.koc.ITbUserThirdIdentityService;
import com.ruoyi.business.service.wecom.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.business.AdjustUserPointsTypeEnum;
import com.ruoyi.common.enums.business.UserKocLevelEnum;
import com.ruoyi.common.enums.business.UserPointsSourceTypeEnum;
import com.ruoyi.common.helper.LoginHelper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 用户 服务层实现
 *
 * @author chenran
 */
@RequiredArgsConstructor
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements ITbUserService {

    @Resource
    private ITbUserThirdIdentityService tbUserThirdIdentityService;

    @Resource
    private final TbKocLevelMapper kocLevelMapper;

    @Resource
    private TbUserKocPointsLogMapper tbUserKocPointsLogMapper;

    @Resource
    private ITbWecomExternalContactCustomerService tbWecomExternalContactCustomerService;

    @Resource
    private ITbWecomExternalContactCustomerFollowUserService tbWecomExternalContactCustomerFollowUserService;

    @Resource
    private ITbWecomChatGroupMemberService tbWecomChatGroupMemberService;

    @Resource
    private ITbWecomChatGroupService tbWecomChatGroupService;

    @Resource
    private ITbWecomExternalContactFollowUserService tbWecomExternalContactFollowUserService;


    @Override
    public TableDataInfo<TbUser> selectPageList(TbUser user, PageQuery pageQuery) {
        Map<String, Object> params = user.getParams();
        LambdaQueryWrapper<TbUser> lqw = new LambdaQueryWrapper<TbUser>();
        lqw.eq(ObjectUtils.isNotEmpty(user.getStatus()), TbUser::getStatus, user.getStatus());
        lqw.eq(ObjectUtils.isNotEmpty(user.getIsKoc()), TbUser::getIsKoc, user.getIsKoc());
        lqw.eq(ObjectUtils.isNotEmpty(user.getGender()), TbUser::getGender, user.getGender());
        if (StringUtils.isNotEmpty(user.getSearchValue())) {
            lqw.like(TbUser::getMobile, user.getSearchValue()).or().like(TbUser::getNickname, user.getSearchValue());
        }
        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
            TbUser::getCreateTime, params.get("beginTime"), params.get("endTime"));
        Page<TbUser> page = baseMapper.selectPage(pageQuery.build(), lqw);
        return TableDataInfo.build(page);
    }

    @Override
    public int setUserKocLevel(UserKocSetDTO dto) {
        // 查询 用户是否存在
        TbUser tbUser = this.baseMapper.selectById(dto.getUserId());
        if (ObjectUtils.isEmpty(tbUser)) {
            throw new ServiceException("用户id有误");
        }
        if (Objects.equals(dto.getKocLevelId(), UserKocLevelEnum.KOC_0.getKocLevelId())) {
            // 非koc 用户
            return baseMapper.update(null, Wrappers.lambdaUpdate(TbUser.class)
                .set(TbUser::getIsKoc, Constants.FALSE_0)
                .set(TbUser::getKocLevelId, null)
                .set(TbUser::getKocLevelName, "")
                .set(TbUser::getKocLevelTime, null)
                .eq(TbUser::getId, dto.getUserId()));
        } else {
            TbKocLevel tbKocLevel = kocLevelMapper.selectById(dto.getKocLevelId());
            if (ObjectUtils.isEmpty(tbKocLevel)) {
                throw new ServiceException("kocLevelId有误");
            }
            // 更新用户 koc 等级信息
            tbUser.setKocLevelId(tbKocLevel.getId());
            tbUser.setIsKoc(Constants.TRUE_1);
            tbUser.setKocLevelTime(new Date());
            tbUser.setKocLevelName(tbKocLevel.getName());
            return baseMapper.updateById(tbUser);
        }
    }

    @Override
    public int updateUserInfo(UpdateUserDTO dto) {
        LambdaUpdateWrapper<TbUser> tbUserLambdaUpdateWrapper = Wrappers.lambdaUpdate(TbUser.class);
        if (StringUtils.isNotEmpty(dto.getHeadPhoto())) {
            tbUserLambdaUpdateWrapper.set(TbUser::getHeadPhoto, dto.getHeadPhoto());
        }
        if (ObjectUtils.isNotEmpty(dto.getGender())) {
            tbUserLambdaUpdateWrapper.set(TbUser::getGender, dto.getGender());
        }
        if (StringUtils.isNotEmpty(dto.getBirthday())) {
            tbUserLambdaUpdateWrapper.set(TbUser::getBirthday, dto.getBirthday());
        }
        if (StringUtils.isNotEmpty(dto.getNickname())) {
            tbUserLambdaUpdateWrapper.set(TbUser::getNickname, dto.getNickname());
        }
        tbUserLambdaUpdateWrapper.eq(TbUser::getId, dto.getUserId());
        return this.baseMapper.update(null, tbUserLambdaUpdateWrapper);
    }

    @Override
    public TbUser selectByIdForUpdate(Long id) {
        return baseMapper.selectByIdForUpdate(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adjustUserPoints(AdjustUserPointsDTO dto) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        TbUser tbUser = baseMapper.selectByIdForUpdate(dto.getUserId());
        TbUserKocPointsLog log = new TbUserKocPointsLog();
        log.setId(IdWorker.getId());
        log.setType(dto.getType());
        log.setUserId(dto.getUserId());
        log.setUserPhone(tbUser.getMobile());
        log.setUserRealName(tbUser.getRealName());
        log.setUserPointOld(tbUser.getFreePoints());
        log.setUserKocLevelId(tbUser.getKocLevelId());
        log.setKocPoint(dto.getPoints());
        log.setSourceType(UserPointsSourceTypeEnum.ADMIN_DEL.getType());
        log.setRemarks(StringUtils.isNotEmpty(dto.getAdjustReason()) ? dto.getAdjustReason() : StringUtils.EMPTY);
        log.setCreateTime(new Date());
        log.setCreateBy(loginUser.getUsername());
        tbUserKocPointsLogMapper.insert(log);
        LambdaUpdateWrapper<TbUser> tbUserLambdaUpdateWrapper = Wrappers.lambdaUpdate(TbUser.class);
        if (Objects.equals(AdjustUserPointsTypeEnum.PLUSH.getType(), dto.getType())) {
            tbUserLambdaUpdateWrapper.set(TbUser::getFreePoints, tbUser.getFreePoints() + dto.getPoints());
            tbUserLambdaUpdateWrapper.set(TbUser::getTotalPoints, tbUser.getTotalPoints() + dto.getPoints());
        }
        if (Objects.equals(AdjustUserPointsTypeEnum.REDUCE.getType(), dto.getType())) {
            tbUserLambdaUpdateWrapper.set(TbUser::getFreePoints, Math.max((tbUser.getFreePoints() - dto.getPoints()), 0));
            tbUserLambdaUpdateWrapper.set(TbUser::getTotalPoints, Math.max((tbUser.getTotalPoints() - dto.getPoints()), 0));
        }
        tbUserLambdaUpdateWrapper.eq(TbUser::getId, dto.getUserId());
        baseMapper.update(tbUser, tbUserLambdaUpdateWrapper);
        return true;
    }

    @Override
    public TbUserDetailVO getUserDetailById(Long id) {
        // 用户主信息
        TbUser tbUser = this.getById(id);
        // 用户微信信息
        TbUserThirdIdentity tbUserThirdIdentity = tbUserThirdIdentityService.getOne(Wrappers.lambdaQuery(TbUserThirdIdentity.class).eq(TbUserThirdIdentity::getUserId, id));
        // 是否有跟进人
        TbWecomExternalContactCustomer tbWecomExternalContactCustomer = tbWecomExternalContactCustomerService.getOne(Wrappers.lambdaQuery(TbWecomExternalContactCustomer.class)
            .eq(TbWecomExternalContactCustomer::getUnionid, tbUserThirdIdentity.getIdentityUnionId()));
        // 是否已经入群
        long count = tbWecomChatGroupMemberService.count(Wrappers.lambdaQuery(TbWecomChatGroupMember.class)
            .eq(TbWecomChatGroupMember::getStatus, 0)
            .eq(TbWecomChatGroupMember::getUserUnionid, tbUserThirdIdentity.getIdentityUnionId()));

        TbUserDetailVO tbUserDetailVO = TbUserDetailVO.builder().user(tbUser).userThirdIdentity(tbUserThirdIdentity).build();
        if (ObjectUtils.isNotEmpty(tbWecomExternalContactCustomer)) {
            tbUserDetailVO.setFollowUserFlag(true);
            tbUserDetailVO.setCustomer(tbWecomExternalContactCustomer);
            List<TbWecomExternalContactCustomerFollowUser> tbWecomExternalContactCustomerFollowUsers = tbWecomExternalContactCustomerFollowUserService.list(Wrappers.lambdaQuery(TbWecomExternalContactCustomerFollowUser.class)
                .eq(TbWecomExternalContactCustomerFollowUser::getStatus, 0)
                .eq(TbWecomExternalContactCustomerFollowUser::getExternalUserid, tbWecomExternalContactCustomer.getExternalUserid()));
            if (CollectionUtils.isNotEmpty(tbWecomExternalContactCustomerFollowUsers)) {
                Set<String> collect = tbWecomExternalContactCustomerFollowUsers.stream().map(TbWecomExternalContactCustomerFollowUser::getUserId).collect(Collectors.toSet());
                List<TbWecomExternalContactFollowUser> tbWecomExternalContactFollowUsers = tbWecomExternalContactFollowUserService.list(Wrappers.lambdaQuery(TbWecomExternalContactFollowUser.class)
                    .in(TbWecomExternalContactFollowUser::getUserId, collect));
                tbUserDetailVO.setFollowUsers(tbWecomExternalContactFollowUsers);
            }
        } else {
            tbUserDetailVO.setFollowUserFlag(false);
        }
        if (count > 0) {
            tbUserDetailVO.setInWecomGroupFlag(true);
            // 查询加入的群聊信息
            List<TbWecomChatGroupMember> tbWecomChatGroupMember = tbWecomChatGroupMemberService.list(Wrappers.lambdaQuery(TbWecomChatGroupMember.class)
                .select(TbWecomChatGroupMember::getChatId,
                    TbWecomChatGroupMember::getUserId,
                    TbWecomChatGroupMember::getUserUnionid,
                    TbWecomChatGroupMember::getUserType)
                .eq(TbWecomChatGroupMember::getStatus, 0)
                .eq(TbWecomChatGroupMember::getUserUnionid, tbUserThirdIdentity.getIdentityUnionId()));
            Set<String> chatIdSet = tbWecomChatGroupMember.stream().map(TbWecomChatGroupMember::getChatId).collect(Collectors.toSet());
            List<TbWecomChatGroup> tbWecomChatGroups = tbWecomChatGroupService.list(Wrappers.lambdaQuery(TbWecomChatGroup.class).in(TbWecomChatGroup::getChatId, chatIdSet));
            tbUserDetailVO.setChatGroups(tbWecomChatGroups);
        } else {
            tbUserDetailVO.setInWecomGroupFlag(false);
        }
        return tbUserDetailVO;
    }
}
